package com.lxch.gdwxp.demoController;

import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayUtil;
import com.lxch.gdwxp.wxpay.service.WXPayService;
import com.lxch.gdwxp.wxpay.utils.DateTimeUtil;
import com.lxch.gdwxp.wxpay.vo.RespResult;
import com.lxch.gdwxp.wxpay.wxpayconfig.WXPayConfigImpl;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.Map;

/**
 * 购买 兑换码
 */
@Controller
@CrossOrigin("*")
public class PayContrller {
    private final static Logger log = LoggerFactory.getLogger(WXAuthorController.class);

    @Resource
    private WXPayService wxPayService;

    @Resource
    private WXPay wxpay;

    @RequestMapping("/wxPay")
    public String wxPay(HttpSession session, Model model) {
        try {
            //弄点参数到wxPay页面。。。。。。。。。。。。
            return "wxPay";
        }catch (Exception e){
            e.printStackTrace();
            return "error";
        }
    }

    @RequestMapping("/payDrink")
//    @ResponseBody
    public String payDrink(Integer fastcode, Integer drinkId, HttpSession session, HttpServletRequest req) throws Exception {
//        数据库获取商品和价格。。。。
        //创建订单。。。。。。
        String oppenid = (String) session.getAttribute("openid");
        JSONObject userToken = (JSONObject) req.getSession().getAttribute("tokenn");
        System.out.println(fastcode + "=====" + drinkId + "drinkid" + oppenid + "oppenid");
        System.out.println(userToken + "usertoken==========================");

        if (true) {//创建成功
            //支付订单....
            RespResult rest = payment(req);
            if (rest.getStatus() == 200) {
                log.info("====================支付成功 去付款页面===================");
                return "redirect:http://pin1sheng.cn/drink/wxPay";
//                return rest;
            } else {
                //支付失败 返回失败信息
                session.setAttribute("staus", 401);
                session.setAttribute("failed", "支付失败！！");
                System.out.println("支付失败paycontrller73行==============================");
//                return RespResult.build(401, "支付失败！！");
                return "error";
            }
        } else {//创建订单 返回失败信息
            session.setAttribute("staus", 400);
            session.setAttribute("failed", "created order failed！！");
            session.setAttribute("data", "创建订单失败");
            System.out.println("支付失败paycontrller80行==============================");
//            return RespResult.build(400, "创建订单失败");
            return "error";
        }
    }


    @RequestMapping("/pay/back")
    public void back(HttpServletRequest req, HttpServletResponse resq) throws Exception {
        // 获取支付结果返回参数 并转换成map
            System.out.println("开始支付回调。。。。。进入WXPayConfigImpl.getWXPayReturn(req)方法流转换成map对象");
            Map<String, String> map = WXPayConfigImpl.getWXPayReturn(req);
            System.out.println("============流转换后的map对象"+map+"=================");
            if (map != null) {// 判断支付结果返回参数 是否为null
                System.out.println("ｍａｐ不为null---------------------------------------");
                // 获取支付返回结果return_code，成功就进行下一步判断
                Map<String, String> returnMap = wxPayService.respResultHandle(map);
                String status = returnMap.get("status");
                if (status.equals("200")) {
                    System.out.println("status.equals(\"200\")支付回调数据校验成功。。。。。。。。。。。。。。");
                    String out_trade_no = map.get("out_trade_no");//获取订单号
                    System.out.println("开始更新订单" + out_trade_no + "状态为已经支付=============================");
                    //修改订单状态为已经支付0未支付  1 支付成功 2 兑换完成.........
                    //完成后 通知微信 这边接收到了支付成功消息
                    System.out.println("status.equals(\"200\")支付回调数据校验成功开始响应微信。。。。。。。。。。。。。。");
                    resq.getOutputStream().print(wxPayService.notifyWX("SUCCESS", "OK"));
                } else {
                    String msg = returnMap.get("msg");
                    log.info("=================" + msg + "  中断业务");
                    // 通知微信接收信息成功
                    resq.getOutputStream().print(wxPayService.notifyWX("FALL", msg));
                }
            } else {// 支付返回结果数据获取失败
                log.info("微信支付结果返回为null  没有开启用户信息修改业务");
                resq.getOutputStream().print(wxPayService.notifyWX("FALL", "微信支付返回的结果为null"));
            }
    }

    private RespResult payment(HttpServletRequest req) {
        /**
         *  device_info:设备号终端设备号(门店号或收银设备ID)，默认请传"WEB" 可以不填
         *  notify_url:支付成功后的回调url 通知地址 配置文件中获取
         *  out_trade_no: 商户系统内部订单号
         *  trade_type: 商品id JSAPI 公众号支付 NATIVE 扫码支付 APP APP支付
         *  total_fee: 支付总金额 单位为分 ,订单的价格。
         *  time_expire: 交易结束时间 格式为yyyyMMddHHmmss，如2009年12月25日9点10分10秒表示为20091225091010。
         *  time_start: 订单生成时间， 格式同上 订单失效时间是针对订单号而言的，由于在下一步请求支付的时候有一个必传参数prepay_id只有两小时的有效期，所以在重入时间超过2小时的时候需要重新请求下单接口获取新的prepay_id。
         *  spbill_create_ip 终端ip 用户端ip 从页面解析
         *  product_id：商品id 当trade_type=NATIVE时（即扫码支付），此参数必传。此参数为二维码中包含的商品ID，商户自行定义
         *  fee_type：交易币种 如 CNY
         */
//        String spbill_create_ip = CusAccessObjectUtil.getIpAddress(req);//从request中获取发请求的ip
        String openId = (String) req.getSession().getAttribute("openid");//用户oppenId 前面setOppenId已经获取到了存到session中了
        log.info("104=====pay openid" + openId);
        String fee_type = "CNY";
        String spbill_create_ip = "39.104.98.178";
        Date date = new Date();
        String time_start = DateTimeUtil.dateToStr(date, "yyyyMMddHHmmss");//订单生成时间
        //=====================注意这几个参数begin===================
        String total_fee = 100 + "";//金额 单位分这个参数要根据情况给.........
        String body = "购买商品" + "!!!";
        String out_trade_no = 1234567 + "";//商户系统内部订单号，开发时使用商品订单号
        //===================================end========================
        String trade_type = "JSAPI";//商品id JSAPI 公众号支付 NATIVE 扫码支付 APP APP支付
        String device_info = "";//设备号终端设备号(门店号或收银设备ID)，默认请传"WEB" 可以不填
        String product_id = "";//商品id 当trade_type=NATIVE时（即扫码支付），此参数必传。此参数为二维码中包含的商品ID，商户自行定义
        try {
            //包装 请求参数 + 8 该订单8分钟有效
            Map<String, String> reqParam = wxPayService.reqParam(body, device_info, fee_type, openId, out_trade_no, product_id,
                    spbill_create_ip, time_start, String.valueOf(Long.parseLong(time_start) + 8 * 60), total_fee, trade_type);
            // 调用统一下单接口 获取下单后的返回值
            log.info(out_trade_no + "===================正在调用 统一下单接口");
            System.out.println("===============这是PayController第120行：测试WXPay是否已经注入：" + wxpay);
            Map<String, String> respResult = wxpay.unifiedOrder(reqParam);

            //处理微信支付统一下单接口 返回值
            Map resultMap = wxPayService.respResultHandle(respResult, out_trade_no);
            if ((int) resultMap.get("status") == 200) {

//                //扫码支付 打开这里
//                String code_url = MyWXPayUtil.NATIVEPay(out_trade_no, respResult);
//                req.setAttribute("code_url", code_url);//这个code_url传到生成二维码的处理器
//                return "forward:/qrCode";


                // 转到一个调用公众号支付JSAPI的页面， 页面会发起一个JSAPI请求支付 需要传参数到页面
                // 包装5个参数 注意key的拼写 大小写 生成签名  prepay_id 2小时有效
                String prepay_id = respResult.get("prepay_id");
                //使用WXPayUtil工具类生成32位的随机数
                String nonceStr = WXPayUtil.generateNonceStr();
                // 生成timeStamp
                String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
                Map<String, String> sigResult = wxPayService.getJSAPISig(prepay_id, nonceStr, timeStamp);//按照规则 生成公众号支付需要的签名
                //保存数据到session 后面页面要取数据调用微信支付JS接口
                log.info("paycontrller153行生成调用微信jsapi的sign============================" + sigResult.get("sign"));
                req.getSession().setAttribute("appid", resultMap.get("appid"));
                req.getSession().setAttribute("timeStamp", timeStamp);
                req.getSession().setAttribute("nonceStr", nonceStr);
                req.getSession().setAttribute("pg", prepay_id);
                req.getSession().setAttribute("paySign", sigResult.get("sign"));
                req.getSession().setAttribute("signType", "MD5");
//                Map<String, String> map = new HashMap<>();
//                map.put(WXPayViewConstant.APPID, sigResult.get("appId"));
//                map.put(WXPayViewConstant.TIMESTAMP, timeStamp);
//                map.put(WXPayViewConstant.NONCESTR, nonceStr);
//                map.put(WXPayViewConstant.PG, prepay_id);
//                map.put(WXPayViewConstant.PAYSIGN, sigResult.get("sign"));
//                map.put(WXPayViewConstant.SIGNTYPE, "MD5");
                return RespResult.ok();
            }
            return RespResult.build(400, "支付失败！请稍后再试！");
        } catch (Exception e) {
            // 调用 统一下单接口 异常
            e.printStackTrace();
            log.info(out_trade_no + "=================调用统一下单接口异常 ");
            return RespResult.build(400, "支付失败！请稍后再试！");
        }
    }
}
